// wrapped by build app
define("dojox/xmpp/PresenceService", ["dijit", "dojo", "dojox"], function (dijit, dojo, dojox) {
    dojo.provide("dojox.xmpp.PresenceService");

    dojox.xmpp.presence = {
        UPDATE:201,
        SUBSCRIPTION_REQUEST:202,
//	SUBSCRIPTION_REQUEST_PENDING: 203,
        /* used when 'ask' attribute is absent on a roster item */
        SUBSCRIPTION_SUBSTATUS_NONE:204,

        SUBSCRIPTION_NONE:'none',
        SUBSCRIPTION_FROM:'from',
        SUBSCRIPTION_TO:'to',
        SUBSCRIPTION_BOTH:'both',
        SUBSCRIPTION_REQUEST_PENDING:'pending',

        STATUS_ONLINE:'online',
        STATUS_AWAY:'away',
        STATUS_CHAT:'chat',
        STATUS_DND:'dnd',
        STATUS_EXTENDED_AWAY:'xa',
        STATUS_OFFLINE:'offline',

        STATUS_INVISIBLE:'invisible'
    };

    dojo.declare("dojox.xmpp.PresenceService", null, {
        constructor:function (xmppService) {
            this.session = xmppService;
            this.isInvisible = false;
            this.avatarHash = null;
            this.presence = null;
            this.restrictedContactjids = {};
        },

        publish:function (presence) {
            ////console.log("Presence::publish() ", presence);
            this.presence = presence;
            this._setPresence();
        },

        /**
         <presence from='juliet@capulet.com/balcony'>
         <x xmlns='vcard-temp:x:update'>
         <photo>sha1-hash-of-image</photo>
         </x>
         </presence>


         <presence>
         <x xmlns='vcard-temp:x:update'>
         <photo/>
         </x>
         </presence>

         */

        sendAvatarHash:function (avatarHash) {
            this.avatarHash = avatarHash;
            this._setPresence();
        },


        _setPresence:function () {
            var presence = this.presence;
            var p = {xmlns:'jabber:client'};

            if (presence && presence.to) {
                p.to = presence.to;
            }

            if (presence.show && presence.show == dojox.xmpp.presence.STATUS_OFFLINE) {
                p.type = 'unavailable';
            }

            if (presence.show && presence.show == dojox.xmpp.presence.STATUS_INVISIBLE) {
                this._setInvisible();
                this.isInvisible = true;
                return;
            }
            ;

            if (this.isInvisible) {
                //console.log("was invisible, making visible");
                this._setVisible();
            }

            var req = new dojox.string.Builder(dojox.xmpp.util.createElement("presence", p, false));

            if (presence.show && presence.show != dojox.xmpp.presence.STATUS_OFFLINE) {
                req.append(dojox.xmpp.util.createElement("show", {}, false));
                req.append(presence.show);
                req.append("</show>");
            }

            if (presence.status) {
                req.append(dojox.xmpp.util.createElement("status", {}, false));
                req.append(presence.status);
                req.append("</status>");
            }

            if (this.avatarHash) {
                req.append(dojox.xmpp.util.createElement("x", {xmlns:'vcard-temp:x:update'}, false));
                req.append(dojox.xmpp.util.createElement("photo", {}, false));
                req.append(this.avatarHash);
                req.append("</photo>");
                req.append("</x>");
            }


            if (presence.priority && presence.show != dojox.xmpp.presence.STATUS_OFFLINE) {
                if (presence.priority > 127 || presence.priority < -128) {
                    presence.priority = 5;
                }
                req.append(dojox.xmpp.util.createElement("priority", {}, false));
                req.append(presence.priority);
                req.append("</priority>");
            }

            req.append("</presence>");
            this.session.dispatchPacket(req.toString());
        },

        /*

         <iq from='bilbo@tolkien.lit/shire' type='set' id='inv1'>
         <query xmlns='jabber:iq:privacy'>
         <list name='invisible'>
         <item action='deny' order='1'>
         <presence-out/>
         </item>
         </list>
         </query>
         </iq>

         <iq from='bilbo@tolkien.lit/shire' type='set' id='active1'>
         <query xmlns='jabber:iq:privacy'>
         <active name='invisible'/>
         </query>
         </iq>

         Make visible:
         <iq from='bilbo@tolkien.lit/shire' type='set' id='active6'>
         <query xmlns='jabber:iq:privacy'>
         <active/>
         </query>
         </iq>

         */

        toggleBlockContact:function (jid) {
            if (!this.restrictedContactjids[jid]) {
                this.restrictedContactjids[jid] = this._createRestrictedJid();
            }

            this.restrictedContactjids[jid].blocked = !this.restrictedContactjids[jid].blocked;
            //console.log("setting outbound block for ", jid, this.restrictedContactjids[jid]);
            this._updateRestricted();
            return this.restrictedContactjids;
        },


        toggleContactInvisiblity:function (jid) {
            if (!this.restrictedContactjids[jid]) {
                this.restrictedContactjids[jid] = this._createRestrictedJid();
            }

            this.restrictedContactjids[jid].invisible = !this.restrictedContactjids[jid].invisible;
            //console.log("setting outbound presence for ", jid, this.restrictedContactjids[jid]);
            this._updateRestricted();
            return this.restrictedContactjids;
        },

        _createRestrictedJid:function () {
            return {invisible:false, blocked:false};
        },

        _updateRestricted:function () {

            var props = {
                id:this.session.getNextIqId(),
                from:this.session.jid + "/" + this.session.resource,
                type:"set"
            };

            var req = new dojox.string.Builder(dojox.xmpp.util.createElement("iq", props, false));
            req.append(dojox.xmpp.util.createElement("query", {xmlns:"jabber:iq:privacy"}, false));
            req.append(dojox.xmpp.util.createElement("list", {name:"iwcRestrictedContacts"}, false))
            var count = 1;
            for (var jid in this.restrictedContactjids) {
                var item = this.restrictedContactjids[jid];
                //console.log("restricted ", jid, item);
                if (item.blocked || item.invisible) {
                    req.append(dojox.xmpp.util.createElement("item", {value:dojox.xmpp.util.encodeJid(jid), action:"deny", order:count++}, false));
                    if (item.blocked) {
                        req.append(dojox.xmpp.util.createElement("message", {}, true));
                    }
                    if (item.invisible) {
                        req.append(dojox.xmpp.util.createElement("presence-out", {}, true));
                    }
                    req.append("</item>");
                } else {
                    delete this.restrictedContactjids[jid];
                }


            }
            req.append("</list>");
            req.append("</query>");
            req.append("</iq>");
            //console.log("Restricted list: ", req.toString());

            var req2 = new dojox.string.Builder(dojox.xmpp.util.createElement("iq", props, false));
            req2.append(dojox.xmpp.util.createElement("query", {xmlns:"jabber:iq:privacy"}, false));
            req2.append(dojox.xmpp.util.createElement("active", {name:"iwcRestrictedContacts"}, true));
            req2.append("</query>");
            req2.append("</iq>");

            //console.log("Activate list: ", req2.toString());


            this.session.dispatchPacket(req.toString());
            this.session.dispatchPacket(req2.toString());
        },

        _setVisible:function () {
            var props = {
                id:this.session.getNextIqId(),
                from:this.session.jid + "/" + this.session.resource,
                type:"set"
            };
            var req = new dojox.string.Builder(dojox.xmpp.util.createElement("iq", props, false));
            req.append(dojox.xmpp.util.createElement("query", {xmlns:"jabber:iq:privacy"}, false));
            req.append(dojox.xmpp.util.createElement("active", {}, true));
            req.append("</query>");
            req.append("</iq>");
            //console.log(req.toString());
            this.session.dispatchPacket(req.toString());
        },

        _setInvisible:function () {
            //console.log("Setting user as invisible");
            var props = {
                id:this.session.getNextIqId(),
                from:this.session.jid + "/" + this.session.resource,
                type:"set"
            };
            var req = new dojox.string.Builder(dojox.xmpp.util.createElement("iq", props, false));
            req.append(dojox.xmpp.util.createElement("query", {xmlns:"jabber:iq:privacy"}, false));
            req.append(dojox.xmpp.util.createElement("list", {name:"invisible"}, false))
            req.append(dojox.xmpp.util.createElement("item", {action:"deny", order:"1"}, false))
            req.append(dojox.xmpp.util.createElement("presence-out", {}, true));
            req.append("</item>");
            req.append("</list>");
            req.append("</query>");
            req.append("</iq>");


            props = {
                id:this.session.getNextIqId(),
                from:this.session.jid + "/" + this.session.resource,
                type:"set"
            };

            var req2 = new dojox.string.Builder(dojox.xmpp.util.createElement("iq", props, false));
            req2.append(dojox.xmpp.util.createElement("query", {xmlns:"jabber:iq:privacy"}, false));
            req2.append(dojox.xmpp.util.createElement("active", {name:"invisible"}, true));
            req2.append("</query>");
            req2.append("</iq>");
            //console.log(req.toString());
            //console.log(req2.toString());
            this.session.dispatchPacket(req.toString());
            this.session.dispatchPacket(req2.toString());
        },

        _manageSubscriptions:function (contact, type) {
            if (!contact) {
                return;
            }

            if (contact.indexOf('@') == -1) {
                contact += '@' + this.session.domain;
            }

            var req = dojox.xmpp.util.createElement("presence", {to:contact, type:type}, true);
            this.session.dispatchPacket(req);

        },

        subscribe:function (contact) {
            this._manageSubscriptions(contact, "subscribe");
        },

        approveSubscription:function (contact) {
            this._manageSubscriptions(contact, "subscribed");
        },

        unsubscribe:function (contact) {
            this._manageSubscriptions(contact, "unsubscribe");
        },

        declineSubscription:function (contact) {
            this._manageSubscriptions(contact, "unsubscribed");
        },

        cancelSubscription:function (contact) {
            this._manageSubscriptions(contact, "unsubscribed");
        }

    });

});
